<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>打开控制台查看结果</div>

<script>
    console.log('============Promise.prototype.catch()============');
    /* 
       Promise.prototype.catch()方法是.then(null,rejection)的别名，也就是说，catch其实是用来指定发生错误时的回调函数。
    */
   let p = new Promise((resolve,reject)=>{
        reject('错误信息')
   })
   p.then(el=>{
    // sth...
   }).catch(err=>{
    console.log(err);  // 错误信息
   })
   /* 上述代码中，p方法返回Promise对象，该对象返回的是reject
      .then方法调用回调函数，then有两个参数，一个resolved和rejected，如果Promise返回的是reject，那么.then的状态就会变成rejected，rejected会调用catch()方法指定的回调函数，处理该错误，catch的参数就是reject抛出的错误信息。
    */

    /* 如果then运行中抛出错误，也会被catch()捕获。 */
   let p2 = new Promise((resolve,reject)=>{
      resolve(100)
   })
   p2.then(el=>{
      throw new Error('then抛错')
   }).catch(err=>{
    console.log(err);  // Error: then抛错
   })


   /* catch捕捉错误的方式 */
   // 方式一
   let promise = new Promise(function(resolve,reject){
      try {
         throw new Error('方式一错误')
      } catch(e){
         reject(e)
      }
   })
   promise.catch(err=>{
   console.log(err);  //  方式一错误
   })

   // 方式二
   let promise2 = new Promise(function(resolve,reject){
      reject(new Error('方式二错误'))
   })
   promise2.catch(err=>{
      console.log(err);  //  方式二错误
   })

   // 方式三
   let promise3 = new Promise((resolve,reject)=>{
      reject('方式三错误')
   })
   promise3.catch(err=>{
      console.log(err);  // 方式三错误
   })

   // 以上三种效果是一样的，前两种通过Error抛出异常，后一种直接抛出异常
   // catch返回的也是一个Promise对象，后面还可以接着.then


   /* 如果Promise的状态变成resolved，那么在抛出错误是无效的，因为Promise的状态一旦发生改变，就会永久保持该状态。 */


   /* Promise内部错误不会影响到到异步队列中的Promise外部代码，同步代码还是会造成阻塞 */
   let p3 = new Promise((resolve,reject)=>{
      resolve(str)  // ReferenceError: str is not defined
   })
   p3.then(el=>{console.log(el)})
   setTimeout(()=>{console.log('Promise外部代码')},0)  // Promise外部代码
   console.log('同步代码');  // 未打印
   
</script>
</body>
</html>